
/*
    Void* Typemap
*/
%typemap(cstype) void*, void*&, void** "global::System.IntPtr"
%typemap (imtype, out="global::System.IntPtr") void*, void*&, void** "global::System.IntPtr"
%typemap(csin) void*, void*&, void** "$csinput"
%typemap(csout, excode=SWIGEXCODE) void*, void*&, void** {
    global::System.IntPtr cPtr = $imcall; $excode
    return cPtr;
}

/*
    char* Typemap
*/
%typemap(cstype, out = "global::System.IntPtr") char*, char**, const char* "ref global::System.IntPtr"
%typemap(imtype, out ="global::System.IntPtr") char*, char**, const char* "ref global::System.IntPtr"
%typemap(csin) char*, char**, const char* "ref $csinput"
%typemap(csout, excode=SWIGEXCODE) char*, char**, const char* {
    global::System.IntPtr cPtr = $imcall; $excode
    return cPtr;
}

%define BASE_TYPE_MAP(TYPE, MAP_TYPE)
%typemap(ctype) TYPE, const TYPE "TYPE"
%typemap(cstype) TYPE, const TYPE "MAP_TYPE"
%typemap(imtype) TYPE, const TYPE "MAP_TYPE"
%typemap(out) TYPE, const TYPE %{
    TYPE oresult = (TYPE)$1;
    $result = oresult;
%}
%typemap(csin) TYPE, const TYPE "$csinput"
%typemap(csout, excode=SWIGEXCODE) TYPE, const TYPE {
    MAP_TYPE r = $imcall; $excode
    return r;
}
%enddef 

%define BASE_POINTER_MAP(TYPE, MAP_TYPE)
%typemap(ctype, out="TYPE") TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& "TYPE*";
%typemap(cstype, out="MAP_TYPE") TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& "ref MAP_TYPE";
%typemap(imtype, out="MAP_TYPE") TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& "ref MAP_TYPE";
%typemap(in) TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& %{
    $1 = $input;
%}
%typemap(out) TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& %{
    TYPE oresult = *$1;
    $result = oresult;
%}
%typemap(csin) TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& "ref $csinput";
%typemap(csout, excode=SWIGEXCODE) TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& {
    MAP_TYPE result = $imcall; $excode
    return result;
}
%typemap(csvarout, excode=SWIGEXCODE2) TYPE*, TYPE*&, const TYPE*, TYPE&, const TYPE& 
%{
    get
    {
        MAP_TYPE result = $imcall; $excode
        return result;
    }
%}
%enddef

BASE_TYPE_MAP(char16_t, char)
BASE_TYPE_MAP(char32_t, uint)
BASE_TYPE_MAP(char, sbyte)
BASE_TYPE_MAP(unsigned char, byte)
BASE_TYPE_MAP(wchar_t, uint)
BASE_TYPE_MAP(bool, bool)
BASE_TYPE_MAP(int, int)
BASE_TYPE_MAP(double, double)
BASE_TYPE_MAP(float, float)
BASE_TYPE_MAP(uint64_t, ulong)
BASE_TYPE_MAP(int64_t, long)
BASE_TYPE_MAP(intptr_t, global::System.IntPtr)

BASE_POINTER_MAP(int, int)
BASE_POINTER_MAP(double, double)
BASE_POINTER_MAP(float, float)
BASE_POINTER_MAP(bool, bool)
BASE_POINTER_MAP(unsigned char, byte)
BASE_POINTER_MAP(uint64_t, ulong)
BASE_POINTER_MAP(int64_t, long)
BASE_POINTER_MAP(intptr_t, global::System.IntPtr)

%typemap(imtype,
outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.I1)]") bool, const bool "bool"

/*
    char16_t* typemap
*/
%typemap(cstype, out = "global::System.IntPtr") char16_t*, char16_t*&, const char16_t* "string"
%typemap(cstype, out = "char") char16_t&, const char16_t& "ref char"
%typemap(imtype, out ="global::System.IntPtr") char16_t*, char16_t*&, const char16_t* "global::System.IntPtr"
%typemap(imtype, out = "char") char16_t&, const char16_t& "ref char"
%typemap(csin, 
    pre= "  unsafe {
        fixed(byte* p = global::System.Text.Encoding.Unicode.GetBytes($csinput)) {
            IntPtr temp$csinput = new IntPtr(p);",
    terminator = "      }
    }"
) char16_t*, char16_t*&, const char16_t* "temp$csinput"
%typemap(csout, excode=SWIGEXCODE) char16_t*, char16_t*&, const char16_t* {
    global::System.IntPtr cPtr = $imcall;
    return cPtr;
}
%typemap(csin) char16_t&, const char16_t& "ref $csinput"
%typemap(csout, excode=SWIGEXCODE) char16_t&, const char16_t& {
    char r = $imcall; $excode
    return r;
}

/*
    wchar_t* typemap
*/
%typemap(cstype, out = "global::System.IntPtr") wchar_t*, wchar_t*&, const wchar_t* "string"
%typemap(imtype, out ="global::System.IntPtr") wchar_t*, wchar_t*&, const wchar_t* "global::System.IntPtr"
%typemap(csin, 
    pre= "  unsafe {
        byte[] local = global::System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(global::System.Runtime.InteropServices.OSPlatform.Windows) ?
        global::System.Text.Encoding.Unicode.GetBytes($csinput) : global::System.Text.Encoding.UTF32.GetBytes($csinput);
        fixed(byte* p = local) {
            IntPtr temp$csinput = new IntPtr(p);",
    terminator = "      }
    }"
) wchar_t*, wchar_t*&, const wchar_t* "temp$csinput"
%typemap(csout, excode=SWIGEXCODE) wchar_t*, wchar_t*&, const wchar_t* {
    global::System.IntPtr cPtr = $imcall; $excode
    return cPtr;
}

/*
    char32_t* typemap
*/
%typemap(cstype, out = "global::System.IntPtr") char32_t*, char32_t*&, const char32_t* "string"
%typemap(imtype, out ="global::System.IntPtr") char32_t*, char32_t*&, const char32_t* "global::System.IntPtr"
%typemap(csin, 
    pre= "  unsafe {
        fixed(byte* p = global::System.Text.Encoding.UTF32.GetBytes($csinput)) {
            IntPtr temp$csinput = new IntPtr(p);",
    terminator = "      }
    }"
) char32_t*, char32_t*&, const char32_t* "temp$csinput"
%typemap(csout, excode=SWIGEXCODE) char32_t*, char32_t*&, const char32_t* {
    global::System.IntPtr cPtr = $imcall; $excode
    return cPtr;
}

%typemap(cstype) SWIGTYPE *& "$*csclassname"
%typemap(imtype, out ="global::System.IntPtr") SWIGTYPE *& "global::System.IntPtr"
%typemap(csin) SWIGTYPE *& "SWIGTYPE.getCPtr($csinput)"
%typemap(csout, excode=SWIGEXCODE) SWIGTYPE *& {
    global::System.IntPtr cPtr = $imcall; $excode
    return new $*csclassname(cPtr, true);
}

%typemap(cstype, out = "global::System.IntPtr") jmp_buf, jmp_buf*, jmp_buf& "global::System.IntPtr"
%typemap(imtype, out ="global::System.IntPtr") jmp_buf, jmp_buf*, jmp_buf& "global::System.IntPtr"
%typemap(csin) jmp_buf, jmp_buf*, jmp_buf& "$csinput"
%typemap(csout, excode=SWIGEXCODE) jmp_buf, jmp_buf*, jmp_buf& {
    global::System.IntPtr cPtr = $imcall; $excode
    return cPtr;
}


 %pragma(csharp) imclassbase = %{
    NativeLoader
 %}

 %define %enum_wrapper(TYPE)
 %typemap(cstype) TYPE, const TYPE "TYPE"
 %typemap(cstype, out = "TYPE") TYPE&, const TYPE&, TYPE*, const TYPE* "ref TYPE"
 %typemap(imtype) TYPE, const TYPE "TYPE"
 %typemap(imtype, out = "TYPE") TYPE&, const TYPE&, const TYPE&, TYPE*, const TYPE* "ref TYPE"
 %typemap(csin) TYPE, const TYPE "$csinput"
 %typemap(csin) TYPE&, const TYPE&, const TYPE&, TYPE*, const TYPE* "ref $csinput"
 %typemap(csout, excode=SWIGEXCODE) TYPE, const TYPE, TYPE&, const TYPE&, const TYPE&, TYPE*, const TYPE* {
    TYPE result = $imcall; $excode
    return result;
 }
 %enddef

 typedef long long ptrdiff_t;

